﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;
using Negocio.Entidades;
using Negocio.Gestores;


namespace Negocio.AccesoDatos
{
    public class ClientesDAO : AccesoADatos
    {
        
        public ClientesDAO() { }


        public static void grabarCliente(Cliente cliente)
        {
            SqlCommand cmd = new SqlCommand();
            SqlCommand cmd2 = new SqlCommand();
            SqlCommand cmd3 = new SqlCommand();
            SqlTransaction trans = null;
            bool graboDomicilio = false;

            SqlConnection con = obtenerConexion();

            try
            {
                trans = con.BeginTransaction();
                cmd.Connection = con;
                cmd2.Connection = con;
                cmd3.Connection = con;
                cmd.Transaction = trans;
                cmd2.Transaction = trans;
                cmd3.Transaction = trans;
                
                cmd.Parameters.Add(new SqlParameter("@documento", cliente.NumeroDocumento));
                cmd.Parameters.Add(new SqlParameter("@tipo_documento", cliente.TipoDocumento));
                cmd.Parameters.Add(new SqlParameter("@Nombre", cliente.Nombre));
                cmd.Parameters.Add(new SqlParameter("@Apellido", cliente.Apellido));

                if (cliente.Sexo.HasValue)
                    cmd.Parameters.Add(new SqlParameter("@sexo", cliente.Sexo));
                else
                    cmd.Parameters.Add(new SqlParameter("@sexo", DBNull.Value));

                if(cliente.activo)
                    cmd.Parameters.Add(new SqlParameter("@activo", "1"));
                else
                    cmd.Parameters.Add(new SqlParameter("@activo", "0"));

                if(cliente.FechaAlta!=null)
                    cmd.Parameters.Add(new SqlParameter("@fecha_alta", DateTime.Parse(cliente.FechaAlta.ToString()))); 
                else
                    cmd.Parameters.Add(new SqlParameter("@fecha_alta", DBNull.Value));

                if (cliente.IdCliente.HasValue)
                {
                    cmd.Parameters.Add(new SqlParameter("@Id_cliente", cliente.IdCliente));

                    if (cliente.NumeroTelefono.HasValue)
                        cmd.Parameters.Add(new SqlParameter("@telefono", cliente.NumeroTelefono));
                    else
                        cmd.Parameters.Add(new SqlParameter("@telefono", DBNull.Value));

                    if (cliente.NumeroCaracteristicaTelefono.HasValue)
                        cmd.Parameters.Add(new SqlParameter("@caracteristica", cliente.NumeroCaracteristicaTelefono));
                    else
                        cmd.Parameters.Add(new SqlParameter("@caracteristica", DBNull.Value));

                    if (cliente.TipoTelefono.HasValue)
                        cmd.Parameters.Add(new SqlParameter("@tipo_telefono", cliente.TipoTelefono));
                    else
                        cmd.Parameters.Add(new SqlParameter("@tipo_telefono", DBNull.Value));

                    cmd.Parameters.Add(new SqlParameter("@mail", cliente.Email));


                    cmd.CommandText = "UPDATE cliente SET documento = @documento, tipo_documento = @tipo_documento, nombre = @nombre,"+
                        " apellido = @apellido, sexo = @Sexo, activo = @activo WHERE id_cliente = @Id_cliente";
                    
                   
                    //actualizar Telefono
                    if (cliente.NumeroTelefono.HasValue)
                    {
                        cmd.CommandText += "; UPDATE telefonoXcliente SET telefono = @telefono,"+
                            " caracteristica = @caracteristica, tipo_telefono = @tipo_telefono WHERE id_cliente = @Id_cliente";
                    }
                    //actualizar Email
                    cmd.CommandText += "; UPDATE mailXcliente SET mail = @mail WHERE id_cliente = @Id_cliente";

                    cmd.ExecuteNonQuery();
                    //actualizar Domicilio
                    GestorDomicilio.grabarDomicilio(cliente.domicilio);
                }
                else
                {
                    if (cliente.NumeroTelefono.HasValue)
                        cmd2.Parameters.Add(new SqlParameter("@telefono", cliente.NumeroTelefono));
                    else
                        cmd2.Parameters.Add(new SqlParameter("@telefono", DBNull.Value));

                    if (cliente.NumeroCaracteristicaTelefono.HasValue)
                        cmd2.Parameters.Add(new SqlParameter("@caracteristica", cliente.NumeroCaracteristicaTelefono));
                    else
                        cmd2.Parameters.Add(new SqlParameter("@caracteristica", DBNull.Value));

                    if (cliente.TipoTelefono.HasValue)
                        cmd2.Parameters.Add(new SqlParameter("@tipo_telefono", cliente.TipoTelefono));
                    else
                        cmd2.Parameters.Add(new SqlParameter("@tipo_telefono", DBNull.Value));

                    cmd3.Parameters.Add(new SqlParameter("@mail", cliente.Email));

                    //Primero Grabar Domicilio
                    cliente.domicilio.id_domicilio = GestorDomicilio.grabarDomicilio(cliente.domicilio);
                    cmd.Parameters.Add(new SqlParameter("@id_domicilio", cliente.domicilio.id_domicilio));
                    graboDomicilio = true;
                    //grabamos el Cliente
                    cmd.CommandText = "INSERT INTO cliente(documento, tipo_documento, nombre, apellido, id_domicilio, fecha_alta, sexo, activo) VALUES(@documento, @tipo_documento, @Nombre, @apellido, @id_domicilio, @fecha_alta, @sexo, @activo); SELECT @@identity;";
                    cliente.IdCliente = int.Parse(cmd.ExecuteScalar().ToString());

                    //grabar Telefono 
                    if (cliente.NumeroTelefono.HasValue)
                    {
                        cmd2.CommandText = "INSERT INTO TelefonoXCliente(id_cliente, telefono, caracteristica, tipo_telefono) VALUES(@Id_cliente, @telefono, @caracteristica, @tipo_telefono)";
                        cmd2.Parameters.Add(new SqlParameter("@Id_cliente", cliente.IdCliente));
                        cmd2.ExecuteNonQuery();
                    }

                    //grabar Mail
                    cmd3.CommandText = "INSERT INTO MailXCliente(id_cliente, mail) VALUES(@Id_cliente, @mail)";
                    cmd3.Parameters.Add(new SqlParameter("@Id_cliente", cliente.IdCliente));
                    cmd3.ExecuteNonQuery();
                }

                trans.Commit();
            }
            catch (SqlException ex)
            {
                if (trans != null && graboDomicilio)
                {
                    GestorDomicilio.eliminarDomicilio(int.Parse(cliente.domicilio.id_domicilio.ToString()));
                    trans.Rollback();
                }
                throw new ApplicationException("Error al ejecutar la transaccion en la Base de Datos. " + ex.Message.ToString());
            }
            finally
            {
                cerrarConexion(con);
            }
        }
        
        public static void eliminarCliente(int id_cliente)
        {

            SqlCommand cmd2 = new SqlCommand();            
            SqlTransaction trans1 = null;
            SqlConnection con = obtenerConexion();
            Cliente cli=obtenerCliente(id_cliente);

            try
            {
                trans1 = con.BeginTransaction();
                cmd2.Connection = con;
                cmd2.Transaction = trans1;
               
                cmd2.CommandText = "DELETE FROM TelefonoXCliente WHERE id_cliente = @Id_cliente; " +
                    "DELETE FROM mailXcliente WHERE id_cliente = @Id_cliente; "+
                    "DELETE FROM cliente WHERE id_cliente = @Id_cliente; "+
                    "DELETE FROM Domicilio WHERE id_domicilio = @Id_domicilio";
                cmd2.Parameters.Add(new SqlParameter("@Id_cliente", cli.IdCliente));
                cmd2.Parameters.Add(new SqlParameter("@Id_domicilio", cli.domicilio.id_domicilio));
                cmd2.ExecuteNonQuery();

                trans1.Commit();
            }
            catch (Exception ex)
            {
                if (trans1 != null)
                {
                    trans1.Rollback();
                }
                throw new ApplicationException("Error al ejecutar la transaccion en la Base de Datos. " + ex.Message.ToString());
            }
            finally
            {
                cerrarConexion(con);
            }
        }

        public static Cliente obtenerCliente(int id_cliente)
        {
            Cliente cliente = new Cliente();
            SqlParameter pr_cli = new SqlParameter("@id_cliente", id_cliente);
            Domicilio dom = new Domicilio();
            try
            {
                string cadena = "Select c.id_cliente, c.documento as 'Nro Documento', c.tipo_documento, c.nombre as 'Nombre'," +
                    " c.apellido as 'Apellido', c.id_domicilio, d.id_localidad as 'Localidad', p.id_provincia as 'Provincia', " +
                    "p.id_pais as 'Pais', d.calle as 'Calle', d.numero as 'Nro', d.piso as 'Piso', d.departamento as 'Dpto', " +
                    "d.barrio as 'Barrio', d.codigoPostal as 'Codigo Postal', c.fecha_alta as 'Fecha de Alta', c.sexo as 'Sexo', c.activo, " +
                    " m.mail as 'E-mail', t.caracteristica as 'Caracteristica', t.telefono as 'Telefono', t.tipo_telefono from Cliente c " +
                    "left outer join Domicilio d on c.id_domicilio=d.id_domicilio left outer join MailXCliente m on c.id_cliente=m.id_cliente" +
                    " left outer join TelefonoXCliente t on c.id_cliente=t.id_cliente left outer join Ciudad ciu on ciu.id_ciudad=d.id_localidad " +
                    "left outer join Provincia p on ciu.id_provincia=p.id_provincia "+
                    "where c.id_cliente=@id_cliente";
                DataTable dt = consultarSQL(cadena, pr_cli);
                cliente.IdCliente = int.Parse(dt.Rows[0]["id_cliente"].ToString());
                cliente.NumeroDocumento = long.Parse(dt.Rows[0]["Nro Documento"].ToString());
                cliente.TipoDocumento = int.Parse(dt.Rows[0]["tipo_documento"].ToString());
                cliente.Nombre = dt.Rows[0]["Nombre"].ToString();
                cliente.Apellido = dt.Rows[0]["Apellido"].ToString();
                if (dt.Rows[0]["Fecha de Alta"] != DBNull.Value)
                    cliente.FechaAlta = DateTime.Parse(dt.Rows[0]["Fecha de Alta"].ToString()).Date.ToShortDateString();
                if (dt.Rows[0]["Sexo"] != DBNull.Value)
                    cliente.Sexo = char.Parse(dt.Rows[0]["Sexo"].ToString());

                if (bool.Parse(dt.Rows[0]["activo"].ToString()))
                    cliente.activo = true;
                else
                    cliente.activo = false;

                if (dt.Rows[0]["E-mail"] != DBNull.Value)
                    cliente.Email = dt.Rows[0]["E-mail"].ToString();
                if (dt.Rows[0]["Caracteristica"] != DBNull.Value)
                    cliente.NumeroCaracteristicaTelefono = long.Parse(dt.Rows[0]["Caracteristica"].ToString());
                if (dt.Rows[0]["Telefono"] != DBNull.Value)
                    cliente.NumeroTelefono = long.Parse(dt.Rows[0]["Telefono"].ToString());
                if (dt.Rows[0]["tipo_telefono"] != DBNull.Value)
                    cliente.TipoTelefono = int.Parse(dt.Rows[0]["tipo_telefono"].ToString());
                if (dt.Rows[0]["id_domicilio"] != DBNull.Value)
                {
                    dom.id_domicilio = int.Parse(dt.Rows[0]["id_domicilio"].ToString());
                    dom.id_localidad = int.Parse(dt.Rows[0]["Localidad"].ToString());
                    dom.id_provincia = int.Parse(dt.Rows[0]["Provincia"].ToString());
                    dom.id_pais = int.Parse(dt.Rows[0]["Pais"].ToString());
                    dom.calle = dt.Rows[0]["Calle"].ToString();
                    dom.numero = int.Parse(dt.Rows[0]["Nro"].ToString());
                    if (dt.Rows[0]["Piso"] != DBNull.Value)
                        dom.piso = int.Parse(dt.Rows[0]["Piso"].ToString());
                    if (dt.Rows[0]["Dpto"] != DBNull.Value)
                        dom.departamento = dt.Rows[0]["Dpto"].ToString();
                    if (dt.Rows[0]["Barrio"] != DBNull.Value)
                        dom.barrio = dt.Rows[0]["Barrio"].ToString();
                    if (dt.Rows[0]["Codigo Postal"] != DBNull.Value)
                        dom.cod_postal = int.Parse(dt.Rows[0]["Codigo Postal"].ToString());
                }
                cliente.domicilio = dom;
            }
            catch (Exception ex)
            {
                
                throw new ApplicationException(ex.Message);
            }

            return cliente;
        }

        public static List<Cliente> obtenerTodos()
        {
            List<Cliente> clientes = new List<Cliente>();
            try
            {
                string cadena = "Select c.id_cliente, c.documento as 'Nro Documento', c.tipo_documento, c.nombre as 'Nombre',"+
                    " c.apellido as 'Apellido', c.id_domicilio, d.id_localidad as 'Localidad', p.id_provincia as 'Provincia', "+
                    "p.id_pais as 'Pais', d.calle as 'Calle', d.numero as 'Nro', d.piso as 'Piso', d.departamento as 'Dpto', "+
                    "d.barrio as 'Barrio', d.codigoPostal as 'Codigo Postal', c.fecha_alta as 'Fecha de Alta', c.sexo as 'Sexo', c.activo,"+
                    " m.mail as 'E-mail', t.caracteristica as 'Caracteristica', t.telefono as 'Telefono', t.tipo_telefono from Cliente c "+
                    "left outer join Domicilio d on c.id_domicilio=d.id_domicilio left outer join MailXCliente m on c.id_cliente=m.id_cliente"+
                    " left outer join TelefonoXCliente t on c.id_cliente=t.id_cliente left outer join Ciudad ciu on ciu.id_ciudad=d.id_localidad "+
                    "left outer join Provincia p on ciu.id_provincia=p.id_provincia";
                SqlDataReader dr = consultarSqlDReader(cadena);
                while (dr.Read())
                {
                    Cliente cliente = new Cliente();
                    Domicilio dom = new Domicilio();
                    cliente.IdCliente = (int)dr["id_cliente"];
                    cliente.NumeroDocumento = long.Parse(dr["Nro Documento"].ToString());
                    cliente.TipoDocumento = int.Parse(dr["tipo_documento"].ToString());
                    cliente.Nombre = dr["Nombre"].ToString();
                    cliente.Apellido = dr["Apellido"].ToString();
                    if (dr["Fecha de Alta"] != DBNull.Value)
                        cliente.FechaAlta = DateTime.Parse(dr["Fecha de Alta"].ToString()).Date.ToShortDateString();
                    if (dr["Sexo"] != DBNull.Value)
                        cliente.Sexo = char.Parse(dr["Sexo"].ToString());

                    if (bool.Parse(dr["activo"].ToString()))
                        cliente.activo = true;
                    else
                        cliente.activo = false;

                    if (dr["E-mail"] != DBNull.Value)
                        cliente.Email = dr["E-mail"].ToString();
                    if (dr["Telefono"] != DBNull.Value)
                        cliente.NumeroTelefono = long.Parse(dr["Telefono"].ToString());
                    if (dr["Caracteristica"] != DBNull.Value)
                        cliente.NumeroCaracteristicaTelefono = long.Parse(dr["Caracteristica"].ToString());
                    if (dr["tipo_telefono"] != DBNull.Value)
                        cliente.TipoTelefono = int.Parse(dr["tipo_telefono"].ToString());
                    if (dr["id_domicilio"] != DBNull.Value)
                    {
                        dom.id_domicilio = int.Parse(dr["id_domicilio"].ToString());
                        dom.id_localidad = int.Parse(dr["Localidad"].ToString());
                        dom.id_provincia = int.Parse(dr["Provincia"].ToString());
                        dom.id_pais = int.Parse(dr["Pais"].ToString());
                        dom.calle = dr["Calle"].ToString();
                        dom.numero = int.Parse(dr["Nro"].ToString());
                        if (dr["Piso"] != DBNull.Value)
                            dom.piso = int.Parse(dr["Piso"].ToString());
                        if (dr["Dpto"] != DBNull.Value)
                            dom.departamento = dr["Dpto"].ToString();
                        if (dr["Barrio"] != DBNull.Value)
                            dom.barrio = dr["Barrio"].ToString();
                        if (dr["Codigo Postal"] != DBNull.Value)
                            dom.cod_postal = int.Parse(dr["Codigo Postal"].ToString());
                    }
                   
                    clientes.Add(cliente);
                }
            }
            catch (Exception ex)
            {

                throw new ApplicationException(ex.Message + "Error al leer todos los clientes. ");
            }

            return clientes;

        }
        
    }
}